part of '../json.dart';

/// 通常用于传输后对Map进行某种检查、寻找等操作
extension JsonMapProcessing on Json {
  /// 当map中存在某种类型的key（通常建议为primitive types）
  /// 则运行onKey函数，否则不运行
  /// 由于有可能存在key，但是值故意设定为null的情况，因此需要手动检查key是否存在
  ifKey<T>(
    String key, {
    required Function(T x) onKey,
    Function? onNull,
    Function? onNoKey,
  }) {
    // 如果map中不存在key，则调用onNoKey
    if (!containsKey(key)) return onNoKey?.call();
    // 读取key对应的value
    final value = this[key];
    // 如果value为null，则调用onNull
    if (value == null) return onNull?.call();
    // 如果value不是T类型，则抛出异常
    if (value is! T) throw Bug('key [$key]对应的类型为${value.runtimeType}，并非$T');
    // 如果value是T类型，则调用onKey
    return onKey(value);
  }

  /// 只允许key存在的情况，否则一律报错
  onKey<T>(String key, Function(T x) onKey) => ifKey<T>(
        key,
        onKey: onKey,
        onNoKey: () => throw Bug("key[$key]未传入"),
        onNull: () => throw Bug("key[$key]为Null"),
      );

  T? find<T>(String key) {
    // 如果key不存在，则返回null
    if (!containsKey(key)) return null;
    // 如果key为null，则返回null
    final result = this[key];
    if (result == null) return null;
    // 如果类型不符合，则报错
    if (result is! T) {
      throw Bug("对应的值result为类型[${result.runtimeType}]，不符合需要的类型$T");
    }
    // 如果值存在，则最终返回
    return result;
  }

  T getField<T>(String key, [String? message]) {
    // 如果key不存在，则报错
    final result = find<T>(key);
    if (result == null) throw Bug(message ?? "key[$key]为空或不存在");
    return result;
  }
}
